// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

import Shader from "../Shader";



const { ccclass, property, executeInEditMode } = cc._decorator;

@ccclass
@executeInEditMode
export default class DissolveShader extends Shader {
    @property(cc.Texture2D)
    _noiseMap: cc.Texture2D = null;

    @property(cc.Texture2D)
    get noiseMap() {
        return this._noiseMap;
    }

    set noiseMap(value) {
        if (value !== this._noiseMap) {
            this._noiseMap = value;
            this.updateNoiseMap();
        }
    }

    @property
    _dissolveTime: number = 1;

    @property
    get dissolveTime() {
        return this._dissolveTime;
    }

    set dissolveTime(value: number) {
        this._dissolveTime = value;
    }

    private _threshold: number = 0;

    get threshold() {
        return this._threshold;
    }

    set threshold(value: number) {
        this._threshold = value;
        this.updateThreshold();
    }

    @property
    _borderRange: number = 0;

    @property({
        range: [0, 1]
    })
    get borderRange() {
        return this._borderRange;
    }

    set borderRange(value) {
        if (value !== this._borderRange) {
            this._borderRange = value;
            this.updateBorderRange();
        }
    }

    @property
    _borderColor: cc.Color = cc.Color.WHITE;

    @property
    get borderColor() {
        return this._borderColor;
    }

    set borderColor(value) {
        this._borderColor = value;
        this.updateBorderColor();
    }

    private _tween: cc.Tween = null;
    private _completeCallback: Function = null;
    private _target: any = null;

    protected start(): void {
        this.updateNoiseMap();
        this.updateThreshold();
        this.updateBorderRange();
        this.updateBorderColor();
    }

    private updateNoiseMap() {
        this.material.setProperty("u_noiseMap", this.noiseMap);
    }

    private updateThreshold() {
        this.material.setProperty("u_threshold", this._threshold);
    }

    private updateBorderRange() {
        this.material.setProperty("u_border", this._borderRange);
    }

    private updateBorderColor() {
        this.material.setProperty("u_borderColor", this._borderColor);
    }

    public startDissolve(): void {
        if (this._tween) this._tween.stop();
        this._tween = cc.tween().set({ threshold: 0 }).to(this._dissolveTime, { threshold: 1 });
        if(this._completeCallback){
            this._tween.call(this._completeCallback,this._target);
        }
        this._tween.target(this).start();
    }

    public stopDissolve() {
        if (this._tween) this._tween.stop();
        this.threshold = 0;
    }

    public setCompleteCallback(callback: Function, target: any) {
        this._completeCallback = callback;
        this._target = target;
    }
}
